package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tbit.uqbike.manager.exception.BaseException;
import com.tbit.uqbike.object.pojo.AccountAuth;
import com.tbit.uqbike.object.pojo.dto.UserFundsFlowDownloadDTO;
import com.tbit.uqbike.object.pojo.vo.UserFundsFlowSumVO;
import com.tbit.uqbike.object.pojo.vo.UserFundsFlowVO;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.common.entity.view.PageResult;
import com.tbit.uqbike.service.business.RideLogDetailsService;
import com.tbit.uqbike.service.business.UserFundsFlowService;
import com.tbit.uqbike.webmanager.dao.capital.UserCapitalChangeDao;
import com.tbit.uqbike.webmanager.util.StringUtils;
import com.tbit.uqbike.webmanager.util.csv.CsvExportUtils;
import com.tbit.uqbike.webmanager.util.csv.entity.ExportHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;
import java.util.Objects;
import java.util.UUID;
import java.util.function.IntSupplier;

/**
 * @Author:BUGTian
 * @DATE: 2022/11/19
 */
@Service
public class UserFundsFlowServiceImpl implements UserFundsFlowService {
    @Autowired
    CsvExportUtils csvExportUtils;
    @Autowired
    private UserCapitalChangeDao userCapitalChangeDao;
    @Autowired
    private RideLogDetailsService rideLogDetailsService;

    @Override
    public PageResult<UserFundsFlowVO> queryPage(LoginInfo login, Integer page, Integer size, Date startTime, Date endTime, String phone, Integer changeType, Integer capitalType, Integer businessType) {
        checkTime(startTime, endTime, phone);
        AccountAuth accountAuth = rideLogDetailsService.getAccountAuth(login);
        PageInfo<UserFundsFlowVO> pageInfo = PageHelper.startPage(page, size).doSelectPageInfo(() -> userCapitalChangeDao.selectUserFundsFlow(accountAuth.getBrandId(), accountAuth.getAccountIdList(), startTime == null ? null : startTime.getTime(), endTime == null ? null : endTime.getTime(), phone, changeType, capitalType, businessType));
        return new PageResult<>(page, size, pageInfo.getTotal(), pageInfo.getPages(), pageInfo.getList());
    }

    @Override
    public String download(LoginInfo login, UserFundsFlowDownloadDTO downloadDTO) {
        File tempFile = csvExportUtils.getTempFile();
        try {
            AccountAuth accountAuth = rideLogDetailsService.getAccountAuth(login);
            if (Objects.isNull(downloadDTO.getPhone()) && Objects.isNull(downloadDTO.getStartTime()) && Objects.isNull(downloadDTO.getEndTime())){
                throw new BaseException("请输入手机号或选择时间");
            }
            //兼容前端 输入手机号不传时间 设置默认查询三年的数据(产品要求)
            if (Objects.isNull(downloadDTO.getStartTime()) && Objects.isNull(downloadDTO.getEndTime())){
                LocalDateTime end = LocalDateTime.now();
                LocalDateTime start = end.minusYears(3);
                downloadDTO.setStartTime(Date.from(start.atZone(ZoneId.systemDefault()).toInstant()));
                downloadDTO.setEndTime(Date.from(end.atZone(ZoneId.systemDefault()).toInstant()));
            }
            //查询总条数
            IntSupplier countFn = () -> userCapitalChangeDao.selectUserFundsFlowCount(accountAuth.getBrandId(),
                    accountAuth.getAccountIdList(),  Objects.isNull(downloadDTO.getStartTime()) ? null : downloadDTO.getStartTime().getTime(),  Objects.isNull(downloadDTO.getEndTime()) ? null : downloadDTO.getEndTime().getTime(),
                    downloadDTO.getPhone(), downloadDTO.getChangeType(),
                    downloadDTO.getCapitalType(), downloadDTO.getBusinessType());
            //单次查询数据
            ExportHandler<UserFundsFlowVO> exportHandler = baseEntity -> {
                Long sTime = baseEntity.getStartTime() == null ? null : baseEntity.getStartTime().getTime();
                Long eTime = baseEntity.getEndTime() == null ? null : baseEntity.getEndTime().getTime();
                return userCapitalChangeDao.selectUserFundsFlow(accountAuth.getBrandId(),
                        accountAuth.getAccountIdList(), sTime, eTime, downloadDTO.getPhone(), downloadDTO.getChangeType(),
                        downloadDTO.getCapitalType(), downloadDTO.getBusinessType());
            };
            File file = csvExportUtils.exportBigCsvUseDynamicDate(exportHandler, UserFundsFlowVO.class, countFn,
                    downloadDTO.getStartTime(), downloadDTO.getEndTime(), tempFile, downloadDTO.getFileName());
            String uploadFileName = UUID.randomUUID().toString().replace("-", "");
            return csvExportUtils.uploadZip(tempFile, uploadFileName, file);
        } finally {
            FileUtil.del(tempFile);
        }
    }

    @Override
    public UserFundsFlowSumVO sumTotal(LoginInfo login, Date startTime, Date endTime, String phone, Integer changeType, Integer capitalType, Integer businessType) {
        checkTime(startTime, endTime, phone);
        AccountAuth accountAuth = rideLogDetailsService.getAccountAuth(login);
        return userCapitalChangeDao.selectUserFundsFlowSum(accountAuth.getBrandId(), accountAuth.getAccountIdList(), startTime == null ? null : startTime.getTime(), endTime == null ? null : endTime.getTime(), phone, changeType, capitalType, businessType);
    }

    public void checkTime(Date startTime, Date endTime, String phone) {
        if (StringUtils.isEmpty(phone)) {
            //如果手机号为空，需要限制查询时间区间
            if (DateUtil.between(startTime, endTime, DateUnit.DAY) > 31) {
                throw new BaseException("查询时间范围过大，请缩小查询范围");
            }
        }
    }
}
